package com.xing.lei.happy.utils;

import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.math.BigDecimal;
import java.util.*;


@SuppressWarnings("unchecked")
public class MapUtils {
	public static void clear(Map map) {
		if (isNotEmpty(map)) {
			map.clear();
		}
	}

	public static Map clone(Map map) {
		if (map == null) {
			return null;
		} else {
			return new HashMap(map);
		}
	}

	public static boolean containsKey(Map map, Object key) {
		return map == null ? false : map.containsKey(key);
	}

	public static boolean notContainsKey(Map map, Object key) {
		return !containsKey(map, key);
	}

	public static boolean containsAllKeys(Map map, Object... keys) {
		if (keys == null) {
			return containsKey(map, null);
		}
		for (Object key : keys) {
			if (notContainsKey(map, key)) {
				return false;
			}
		}
		return true;
	}

	public static boolean notContainsAllKeys(Map map, Object... keys) {
		return !containsAllKeys(map, keys);
	}

	public static boolean containsAnyKeys(Map map, Object... keys) {
		if (keys == null) {
			return containsKey(map, null);
		}
		for (Object key : keys) {
			if (containsKey(map, key)) {
				return true;
			}
		}
		return false;
	}

	public static boolean notContainsAnyKeys(Map map, Object... keys) {
		return !containsAnyKeys(map, keys);
	}

	public static boolean containsValue(Map map, Object value) {
		return map == null ? false : map.containsValue(value);
	}

	public static boolean notContainsValue(Map map, Object value) {
		return !containsValue(map, value);
	}

	public static boolean containsAllValues(Map map, Object... values) {
		if (values == null) {
			return containsValue(map, null);
		}
		for (Object value : values) {
			if (notContainsValue(map, value)) {
				return false;
			}
		}
		return true;
	}

	public static boolean notContainsAllValues(Map map, Object... values) {
		return !containsAllValues(map, values);
	}

	public static boolean containsAnyValues(Map map, Object... values) {
		if (values == null) {
			return containsValue(map, null);
		}
		for (Object value : values) {
			if (containsValue(map, value)) {
				return true;
			}
		}
		return false;
	}

	public static boolean notContainsAnyValues(Map map, Object... values) {
		return !containsAnyValues(map, values);
	}










	public static Object getObject(Map map, Object key) {
		return isEmpty(map) ? null : map.get(key);
	}


	public static Boolean getBoolean(Map map, Object key) {
		return ObjectUtils.toBoolean(getObject(map, key));
	}

	public static Short getShort(Map map, Object key) {
		return ObjectUtils.toShort(getObject(map, key));
	}

	public static Integer getInteger(Map map, Object key) {
		return ObjectUtils.toInteger(getObject(map, key));
	}

	public static Long getLong(Map map, Object key) {
		return ObjectUtils.toLong(getObject(map, key));
	}

	public static Float getFloat(Map map, Object key) {
		return ObjectUtils.toFloat(getObject(map, key));
	}

	public static Double getDouble(Map map, Object key) {
		return ObjectUtils.toDouble(getObject(map, key));
	}

	public static BigDecimal getBigDecimal(Map map, Object key) {
		return ObjectUtils.toBigDecimal(getObject(map, key));
	}

	public static Date getDate(Map map, Object key) {
		return ObjectUtils.toDate(getObject(map, key));
	}

	public static Object[] getArray(Map map, Object key) {
		Object obj = getObject(map, key);
		if (obj instanceof Object[]) {
			return (Object[]) obj;
		} else {
			return null;
		}
	}

	public static String[] getStringArray(Map map, Object key) {
		Object obj = getObject(map, key);
		if (obj instanceof String[]) {
			return (String[]) obj;
		} else {
			return null;
		}
	}

	public static Map getMap(Map map, Object key) {
		return ObjectUtils.mapObject(getObject(map, key));
	}

	public static List getList(Map map, Object key) {
		Object obj = getObject(map, key);
		if (obj instanceof List) {
			return (List) obj;
		} else {
			return null;
		}
	}

	public static Object getNode(Map map, Object... keys) {
		if (ObjectUtils.isAllNotBlank(map, keys)) {
			for (int i = 0, len = keys.length; i < len; i++) {
				Object value = map.get(keys[i]);
				if (i == len - 1) {
					return value;
				}
				map = ObjectUtils.mapObject(value);
				if (map == null) {
					break;
				}
			}
		}
		return null;
	}

	public static Map getMapNode(Map map, Object... keys) {
		return ObjectUtils.mapObject(getNode(map, keys));
	}

	public static List getListNode(Map map, Object... keys) {
		Object value = getNode(map, keys);
		if (value instanceof List) {
			return (List) value;
		} else {
			return null;
		}
	}


	public static Boolean getBooleanNode(Map map, Object... keys) {
		return ObjectUtils.toBoolean(getNode(map, keys));
	}

	public static Short getShortNode(Map map, Object... keys) {
		return ObjectUtils.toShort(getNode(map, keys));
	}

	public static Integer getIntegerNode(Map map, Object... keys) {
		return ObjectUtils.toInteger(getNode(map, keys));
	}

	public static Long getLongNode(Map map, Object... keys) {
		return ObjectUtils.toLong(getNode(map, keys));
	}

	public static Float getFloatNode(Map map, Object... keys) {
		return ObjectUtils.toFloat(getNode(map, keys));
	}

	public static Double getDoubleNode(Map map, Object... keys) {
		return ObjectUtils.toDouble(getNode(map, keys));
	}

	public static BigDecimal getBigDecimalNode(Map map, Object... keys) {
		return ObjectUtils.toBigDecimal(getNode(map, keys));
	}

	public static Date getDateNode(Map map, Object... keys) {
		return ObjectUtils.toDate(getNode(map, keys));
	}

	public static boolean isEmpty(Map map) {
		return map == null || map.isEmpty();
	}

	public static boolean isNotEmpty(Map map) {
		return !isEmpty(map);
	}

	public static boolean isMap(Object obj) {
		return obj instanceof Map;
	}

	public static boolean isNotMap(Object obj) {
		return !isMap(obj);
	}

	public static Set keySet(Map map) {
		return map == null ? null : map.keySet();
	}



	public static Object put(Map map, Object key, Object value) {
		return map == null ? null : map.put(key, value);
	}

	public static void putAll(Map map1, Map... map2s) {
		if (map1 != null && ObjectUtils.isNotBlank(map2s)) {
			for (Map map2 : map2s) {
				if (map2 != null) {
					map1.putAll(map2);
				}
			}
		}
	}



	public static Object[] removeKeys(Map map, Object... keys) {
		if (map == null || keys == null) {
			return null;
		}
		int len = keys.length;
		Object[] values = new Object[len];
		for (int i = 0; i < len; i++) {
			values[i] = map.remove(keys[i]);
		}
		return values;
	}

	public static int size(Map map) {
		return map == null ? 0 : map.size();
	}



	public static boolean valueIsBlank(Map map, String key) {
		return ObjectUtils.isBlank(getObject(map, key));
	}

	public static boolean valueIsNotBlank(Map map, String key) {
		return !valueIsBlank(map, key);
	}

	public static Collection values(Map map) {
		if (map == null) {
			return null;
		} else {
			return map.values();
		}
	}
	
	public static MultiValueMap MapToMultiValueMap(Map<String,Object> map) {
		MultiValueMap<String, Object> multiValueMap= new LinkedMultiValueMap<String, Object>();
		if (map == null) {
			return null;
		}else{
			for (String key : map.keySet()) {
				multiValueMap.put(key, Collections.singletonList(map.get(key)));
			}
		}
		return multiValueMap;
	}
}